# -*- coding: utf-8 -*-
import sys
from elasticsearch import Elasticsearch, ElasticsearchException
import re
from project.settings import ES_URL, ES_USER, ES_PASSWORD
from .query import fuzzy_query, mapping_query, ES_INDEX_NAME, ES_DOC_MIX, fuzzy_query_with_subjectid, \
    fuzzy_query_with_q_type, ES_DOC_CHOICE, ES_DOC_UNIVERSAL
import imp

default_encoding = 'utf-8'

if sys.getdefaultencoding() != default_encoding:
    imp.reload(sys)
    sys.setdefaultencoding(default_encoding)


class YJElasticSearch(object):
    def __init__(self):
        self.es = self.init_es()

    @staticmethod
    def init_es():
        try:
            return Elasticsearch(hosts=ES_URL, http_auth=(ES_USER, ES_PASSWORD))
        except ElasticsearchException:
            raise TypeError("Cannot connect to ES server")

    def search(self, content, subjectid=None, type=None, name=1):
        """
        content: 搜索字符串
        size:设置response个数
        type:备用，留作单独检索某个doc_type
        :return:
        dict = {
        _shards:{'successful':5, 'failed':0, total:5},
        hits:{
            max_score:10,
            total:9,
            hits:[_id:40,_index:yijiao_search,_score:101,_score:{content:原始内容},
            _type:universal, highlight:{content:高亮内容}]
                },
        time_out:False,
        took:9,
        }
        """
        # import urllib
        # content = urllib.urlencode(content)
        # import re
        # content = re.escape(content)
        # content = re.sub(r'(\-|\]|\^|\$|\*|\.|\\)',lambda m:{'-':'\-',']':'\]','\\':'\\\\','^':'\^','$':'\$','*':'\*','.':'\.'}[m.group()],content)
        # content.encode('unicode-escape')
        # content = re.sub("\"", "", content.strip())
        content = re.sub("\s|\'|`|\||、", "", re.sub("\"|", "", content.strip())).replace('\\', '')
        body = fuzzy_query_with_subjectid % (content, content, subjectid, name) if subjectid else fuzzy_query % content
        result = self.es.search(index=ES_INDEX_NAME, doc_type=ES_DOC_MIX, body=body, size=10)
        return result

    def search_elephant(self, content, subjectid, type):
        """
        content: 搜索字符串
        size:设置response个数
        type:备用，留作单独检索某个doc_type
        :return:
        dict = {
        _shards:{'successful':5, 'failed':0, total:5},
        hits:{
            max_score:10,
            total:9,
            hits:[_id:40,_index:yijiao_search,_score:101,_score:{content:原始内容},
            _type:universal, highlight:{content:高亮内容}]
                },
        time_out:False,
        took:9,
        }
        """
        content = re.sub("\s|\'|`|\||、", "", re.sub("\"|", "", content.strip())).replace('\\', '')
        # body = fuzzy_query_with_q_type % (content, subjectid, type)
        body = fuzzy_query_with_q_type % (content, subjectid)
        doc_type = ES_DOC_CHOICE if type else ES_DOC_UNIVERSAL
        result = self.es.search(index=ES_INDEX_NAME, doc_type=doc_type, body=body, size=10)
        return result

    def hightlight_elephant(self, result):
        data = []
        for catch in result:
            inner = {
                'id': catch['_id'],
                'score': catch['_score'],
                'type': catch['_type'],
                'origin': catch['_source']['content'],
                # 'highlight': catch['highlight']['content'][0],
                'highlight': catch['_source']['content'],
                'level': catch['_source']['level'],
                'progress': catch['_source']['name'],
                'videourl': catch['_source']['videourl'],
                'answer': catch['_source']['answer'],
                'explanation': catch['_source']['explanation']
            }
            inner['qtag_id'] = catch['_source']['qtag_id'] if inner['type'] == 'universal' else 1
            data.append(inner)
        return data

    def hightlight(self, result):
        data = []
        for catch in result:
            inner = {
                'id': catch['_id'],
                'score': catch['_score'],
                'type': catch['_type'],
                'origin': catch['_source']['content'],
                # 'highlight': catch['highlight']['content'][0],
                'highlight': catch['_source']['content'],
                'level': catch['_source']['level'],
                'progress': catch['_source']['name']
            }
            if inner['type'] == 'universal':
                inner['qtag_id'] = catch['_source']['qtag_id']
                inner['answer'] = catch['_source']['answer']
            # if catch.get('highlight'):
            #     inner['highlight'] = catch['highlight']['content'][0] if catch['highlight'].get('content')
            #  else catch['_source']['content']
            #     if inner['type'] == 'universal':
            #         inner['answer'] = catch['highlight']['answer'][0] if catch['highlight'].get('answer')
            #  else catch['_source']['answer']
            data.append(inner)
        return data

    def create_index(self, index_name):
        """
        es.create_index('tt01')
        """
        try:
            self.es.indices.create(index=index_name)
            return {
                'retcode': 0,
                'msg': 'success'
            }
        except ElasticsearchException as e:
            return {
                'retcode': e.args[0],
                'msg': e.args[1]
            }

    def create_mapping(self, index_name, doc_name, fields, ik='ik_smart'):
        """
        es.create_mapping('tt01', 'dt01', 'content', 'ik_smart')
        :param index_name: 索引名字
        :param doc_name: doc_type 名字
        :param fields: tokenlizer field
        :param ik: ik= ik_smart 或者 ik_max_word
        :return:
        """
        query = mapping_query % (doc_name, ik, ik, fields, ik, ik)
        self.es.indices.put_mapping(doc_type=doc_name, index=index_name, body=query)
        return {
            'retcode': 0,
            'msg': 'success'
        }


def get_result(content, subjectid=None):
    es = YJElasticSearch()
    result = es.search(content, subjectid)
    msg = ''
    if result['hits']['total'] != 0:
        result = es.hightlight(result['hits']['hits'])
        retcode = 0
    else:
        msg = 'no data!'
        retcode = 1
    return {'result': result, 'q': content, 'msg': msg, 'retcode': retcode}
    # return render_to_response("es/index.html", {'result': result, 'q': content, 'msg': msg})


def get_result_elephant(content, subjectid, q_type):
    es = YJElasticSearch()
    result = es.search_elephant(content, subjectid, q_type)
    msg = ''
    if result['hits']['total'] != 0:
        result = es.hightlight_elephant(result['hits']['hits'])
        retcode = 0
    else:
        msg = 'no data!'
        retcode = 1
    return {'result': result, 'q': content, 'msg': msg, 'retcode': retcode}
    # return render_to_response("es/index.html", {'result': result, 'q': content, 'msg': msg})


def create_index(name):
    es = YJElasticSearch()
    return es.create_index(name)


def create_mapping(index_name, doc_name, fields, ik):
    es = YJElasticSearch()
    return es.create_mapping(index_name, doc_name, fields, ik)
